package ar.edu.uba.fi.jmit.aspecter.monitor.methodTime;

import java.util.HashMap;
import java.util.Map;

import javassist.expr.Expr;
import ar.edu.uba.fi.jmit.aspecter.core.Constants;
import ar.edu.uba.fi.jmit.aspecter.core.CoreUtils;
import ar.edu.uba.fi.jmit.aspecter.core.MethodDefinition;
import ar.edu.uba.fi.jmit.aspecter.core.ResourceProperties;
import ar.edu.uba.fi.jmit.aspecter.core.interceptor.MethodAccessInterceptor;

public class MethodTimeMethodInterceptor extends MethodAccessInterceptor {
	
	/**
	 * Nombre del monitoreo
	 */
	private String monitorName;
	
	/**
	 * Prioridad del monitoreo. Por default: Normal.
	 */
	private String priority = ResourceProperties.getProperty(Constants.EVENT_DEFAULT_PRIORITY);
	
	/**
	 * Nombre de la variable creada para contar el tiempo
	 */
	private String timeVariableName = ResourceProperties.getProperty(Constants.DEFAULT_TIME_VARIABLE_NAME);
	
	public MethodTimeMethodInterceptor(String monitorName, MethodDefinition methodDefinition) {
		super(methodDefinition);
		this.monitorName = monitorName;
	}
	
	public MethodTimeMethodInterceptor(String monitorName, MethodDefinition methodDefinition, String priority) {
		this(monitorName, methodDefinition);
		this.priority = priority;
	}

	@Override
	protected String aspectStatementAfter() {
		StringBuffer buff = new StringBuffer();
		buff.append(timeVariableName + " = new java.util.Date().getTime() - " + timeVariableName + ";");//stop counting time
 		Map<String, String> dataMap = new HashMap<String, String>();
 		dataMap.put(ResourceProperties.getProperty(Constants.EVENT_MONITOR_NAME_KEY), "\"" + monitorName + "\"");
 		dataMap.put(ResourceProperties.getProperty(Constants.EVENT_MONITOR_DATE), "new java.util.Date()");
 		dataMap.put(ResourceProperties.getProperty(Constants.METHOD_ELAPSED_TIME), "Long.valueOf(" + timeVariableName + ") ");
 		CoreUtils.createEventCode(buff, priority, "\"" + getSource() + "\"", dataMap, true);
		return buff.toString();
	}
	
	/**
	 * Devuelve el texto que va a ser enviado como "source" en los eventos al monitorEngine
	 * @return
	 */
	protected String getSource() {
		return getMethodDefinition().toString();
	}

	/**
	 * Esta clase siempre tiene una y solo una definicion
	 * @return
	 */
	private MethodDefinition getMethodDefinition() {
		return methodsToIntercept.get(0);
	}

	@Override
	protected String aspectStatementBefore() {
		return " long " + timeVariableName + " = new java.util.Date().getTime();";
	}

	@Override
	public boolean mustAspect(Expr expression) {
		return true;
	}

	public String getPriority() {
		return priority;
	}

	public void setPriority(String priority) {
		this.priority = priority;
	}

	public String getTimeVariableName() {
		return timeVariableName;
	}

	public void setTimeVariableName(String timeVariableName) {
		this.timeVariableName = timeVariableName;
	}

}
